//
//  SerializeHelper.cpp
//  client
//
//  Created by will on 12/05/2017.
//
//

#include "SerializeHelper.hpp"
#include <sstream>
#include "cocos2d.h"

extern "C" {
#include "lua.h"
#include "tolua++.h"
}
#include "tolua_fix.h"

typedef unsigned char BYTE;

#include <sstream>

int SerializeHelper::encodeLua(lua_State* L)
{
    assert(lua_gettop(L)==2);
    int sequence = lua_tointeger(L,1);
    size_t bodysize;
    const char* bodydata = (const char*) lua_tolstring(L,2,&bodysize);
    CCASSERT(bodysize>=0,"encodeLua error");
    
    std::vector<char> buff(4+bodysize);
	buff[0] = static_cast<BYTE>(sequence);
	buff[1] = static_cast<BYTE>(sequence >> 8);
	buff[2] = static_cast<BYTE>(sequence >> 16);
	buff[3] = static_cast<BYTE>(sequence >> 24);

    size_t offset=4;
    for(size_t i=0;i<bodysize;++i){
        buff[offset++] = bodydata[i];
    }
    lua_pushlstring(L, reinterpret_cast<char*>(&buff[0]) , buff.size());
    return 1;
}

int SerializeHelper::decodeLua(lua_State* L)
{
    size_t size = 0;
    const char* data = (const char*) lua_tolstring(L,1, &size);
	int sequence = int(BYTE(data[0])) | int(BYTE(data[1])) << 8 | int(BYTE(data[2])) << 16 | int(BYTE(data[3])) << 24;
    size_t offset = 4;
    size_t bodysize = size - offset;
    std::vector<char> bodybuf(bodysize);
    for(size_t i=0;i<bodysize;++i){
        bodybuf[i] = data[offset++];
    }
	lua_pushinteger(L, sequence);
	const char* bodybufptr = bodysize>0 ? reinterpret_cast<char*>(&bodybuf[0]) : "";
	lua_pushlstring(L, bodybufptr, bodysize);
    return 2;
}



void SerializeHelper::register2lua(lua_State* L)
{
    lua_getglobal(L, "_G");
    if (lua_istable(L, -1))//stack:...,_G,
    {
        tolua_open(L);
        tolua_module(L,"SerializeHelper",0);
        tolua_beginmodule(L,"SerializeHelper");
        tolua_function(L,"encode",&SerializeHelper::encodeLua);
        tolua_function(L,"decode",&SerializeHelper::decodeLua);
        tolua_endmodule(L);
    }
    lua_pop(L, 1);
}
